<!-- 上传组件（文件上传待测试） -->
<template>
  <div class="img-upload" ref="upload">
    <a-upload
      ref="uploadDom"
      v-viewer
      @preview="preview($event, 'uploadDom', config.fileList)"
      @change="handleSuccess"
      :file-list="config.fileList"
      :headers="config.header"
      :data="data"
      :action="config.baseUrl"
      :accept="config.accept"
      :list-type="config.listType"
      :before-upload="beforeUpload"
      :preview-file="type === 'image' ? previewFile : null"
      :disabled="disabled"
      :multiple="limit > 1 || limit === -1"
    >
      <div v-if="config.fileList.length < limit || limit === -1">
        <template v-if="config.listType === 'picture-card'">
          <a-icon type="plus" />
          <div class="ant-upload-text">上传</div>
        </template>
        <template v-else>
          <a-button><a-icon type="upload" />上传附件</a-button>
        </template>
      </div>
    </a-upload>
  </div>
</template>

<script>
import { getToken } from '@/util/method'
import { uploadImgUrl } from '@/util'
import lrz from 'lrz'
export default {
  name: 'upload',
  props: {
    value: {
      type: Array,
      default: () => []
    }, // 上传成功图片地址
    limit: {
      type: Number,
      default: -1
    }, // 上传数量限制
    disabled: {
      type: Boolean,
      default: false
    }, // 是否禁用
    action: {
      type: String,
      default: ''
    }, // 上传接口地址
    accept: {
      type: String,
      default: ''
    }, // 上传类型限制 默认图片类型
    data: {
      type: Object,
      default: () => {
        return {
          fileType: 1
        }
      }
    }, // 给后端带的参数
    type: {
      type: String,
      default: 'image'
    }, // 上传类型 image/file
    Proportion: {
      type: Array,
      default: () => {
        return []
      }
    }, // 图片上传比例
    size: {
      type: Number,
      default: 1.8
    }
  },
  data() {
    return {
      isAction: false, // 是否是上传图片的操作
      urls: [], // 图片数据
      config: {
        header: {
          Authorization: getToken()
        },
        baseUrl: uploadImgUrl,
        fileList: [],
        listType: 'picture-card', // 上传成功展示样式 默认展示图片
        accept: 'image/*' // 上传类型限制
      }
    }
  },
  created() {
    this.initConfig()
    if (this.value.length) this.initImg(this.value)
  },
  watch: {
    value: {
      handler(newValue) {
        if (!this.isAction) this.initImg(newValue)
      },
      deep: true
    }
  },
  methods: {
    // 初始化配置
    initConfig() {
      const { type, accept, action } = this
      if (type === 'file') {
        this.config.listType = 'text'
        this.config.accept = ''
      }
      if (accept) this.config.accept = accept
      if (action) this.config.baseUrl = action
    },
    // 初始化图片展示
    initImg(value) {
      let fileList = []
      this.urls = value
      this.urls.forEach((url, index) => {
        if (url) fileList.push(this.antUrlFormat(url, index))
      })
      this.config.fileList = fileList
    },
    // 上传 失败/成功/删除
    handleSuccess({ fileList, file }) {
      // 截取数量
      const fileLists = this.limit === -1 ? fileList : fileList.filter((item, index) => index < this.limit)
      this.config.fileList = fileLists
      //  上传错误
      if (file.response && file.response.errMessage) {
        this.$messageSend.error(file.response.errMessage)
        const index = this.config.fileList.findIndex((e) => e.name === file.name)
        this.config.fileList.splice(index, 1)
      }
      if (file.response && file.response.code && file.response.code !== 200) {
        this.$messageSend.error(file.response.message)
        const index = this.config.fileList.findIndex((e) => e.name === file.name)
        this.config.fileList.splice(index, 1)
      }
      // 上传成功
      let urls = []
      console.log(fileLists)
      fileLists.forEach((item = {}) => {
        const { response: { data } = {}, status } = item
        let url = ''
        if (Array.isArray(data)) {
          url = data[0] || ''
        } else {
          url = data || ''
        }
        console.log(url)
        if (status === 'done') urls.push(url.path ? url.path : url)
      })
      this.urls = urls
      this.emitUpdate()
    },
    // 更新父组件数据
    emitUpdate() {
      this.isAction = true
      this.$emit('input', this.urls)
      this.$emit('update') // 暴露给父组件用于表单验证 this.$refs.url.onFieldChange()
      this.$nextTick(() => {
        this.isAction = false
      })
    },
    // 压缩图片
    async beforeUpload(file) {
      if (this.Proportion.length > 0) {
        // 限制图片宽高比
        let reader = new FileReader()
        reader.readAsDataURL(file) // 必须用file.raw
        reader.onload = () => {
          // 让页面中的img标签的src指向读取的路径
          let img = new Image()
          img.src = reader.result
          img.onload = () => {
            if (img.width / img.height !== this.Proportion[0] / this.Proportion[1]) {
              this.config.fileList.forEach((item, index) => {
                if (item.uid === file.uid) {
                  this.config.fileList.splice(index, 1)
                }
              })
              console.log('----')
              this.$messageSend.error(`需上传图片宽高比例为${this.Proportion[0]}：${this.Proportion[1]},当前图片${img.width}×${img.height}`)
              return false
            }
            console.log('---22-')
            // 限制图片大小
            const limit = this.size * 1024 * 1024 // 图片限制1.8M 1.8 * 1024 * 1024
            if (file && file.size > limit) {
              lrz(file)
                .then((res) => {
                  let file = new File([res.file], res.origin.name, { type: res.file.type })
                  file.uid = res.origin.uid
                  return file
                })
                .catch((e) => {
                  console.log('压缩失败')
                  this.$messageSend.error('压缩失败，请选择3M以下的图片')
                  return false
                })
            } else {
              return file
            }
          }
        }
      } else {
        // 限制图片大小
        const limit = this.size * 1024 * 1024 // 图片限制1.8M 1.8 * 1024 * 1024
        if (file && file.size > limit) {
          lrz(file)
            .then((res) => {
              let file = new File([res.file], res.origin.name, { type: res.file.type })
              file.uid = res.origin.uid
              return file
            })
            .catch((e) => {
              console.log('压缩失败')
              this.$messageSend.error('压缩失败，请选择3M以下的图片')
              return false
            })
        } else {
          return file
        }
      }
    },
    // ant 上传组件展示图片格式
    antUrlFormat(url, index) {
      const postion = url.lastIndexOf('/') + 1
      const name = url.substr(postion)
      return {
        uid: index + 1 || 1,
        url: url,
        status: 'done',
        name: name,
        response: {
          data: [url]
        }
      }
    },
    // 预览
    preview(e, ref, fileList) {
      if (this.type === 'image') {
        this.$antPreview(e, ref, fileList)
      } else {
        if (e.response) window.open(e.response.data)
      }
    },
    // 预览前更换 base64
    previewFile(file) {
      return new Promise((resolve, reject) => {
        this.getBase64(file).then((res) => {
          resolve(res)
        })
      })
    },
    // file 转 base64
    getBase64(file) {
      return new Promise((resolve, reject) => {
        const reader = new FileReader()
        reader.readAsDataURL(file)
        reader.onload = () => resolve(reader.result)
        reader.onerror = (error) => reject(error)
      })
    }
  }
}
</script>

<style lang="scss" scoped>
/deep/ .ant-upload-list-item-info,
.img-upload {
  margin: 0;
}
</style>
